ホームに戻る
関連 :
仮想関数 (Virtual Function) 仮想デストラクタ 継承と委譲 SOLIDの原則 インタフェース
目次 :

継承とは

あるクラスが、別のクラスの性質(メンバ)を受け継ぐ機構。
あるクラスを基に、機能を追加した別クラスを作成したり、抽象的なクラスから具体化したクラスを作成する際に用いる。
C++に限らず、オブジェクト指向言語では一般的な仕組み。 オブジェクト指向の根幹をなす重要な概念である
画像

基本クラスと派生クラス

あるクラスを作成する際に基となる(継承される)クラスを 「基本 (Base) クラス」 、継承してできたクラスを 「派生 (Derived) クラス」 と呼ぶ。
その他の呼び方は以下を参照。文脈によって使い分けることがある。
「親クラス」「子クラス」は「継承」時だけでなく、「所有」時にも用いられることがあるため注意が必要。
また、「基本クラス」と「抽象クラス」の混同がみられることがあるが、異なるものである
(仮想関数 (Virtual Function)を参照。)

継承を用いることの利点

ひとつの基本クラスから複数の派生クラスを作成する場合に、派生クラス同士で共通する性質と、派生クラスごとに異なる性質を分離することができる。
即ち、共通する性質は基本クラスに実装しておき、派生クラスごとに異なる性質はそれぞれで実装する。
後に基本クラスが修正された場合には派生クラスにも修正内容が反映されるため、 派生クラスでは自身に固有の(親と異なる)性質のみを考慮すればよい
(基本クラスの修正に合わせて、派生クラスの実装を修正する必要が無い)

アクセス指定

// 基本クラス class CBase { private: U2 m_u2_Val; public: void setVal( U2 n ) { m_u2_Val = n; } U2 getVal() { return m_u2_Val; } } // 派生クラス( CBase を public 継承) class CDerived : public CBase { private: U2 m_u2_Val2; public: void setVal( U2 n ) { m_u2_Val2 = n; } }
まず重要な前提として、 「基本クラスの private (非公開)メンバは、派生クラスからはアクセスできない」 ことが挙げられる。
基本クラスにおける 「(自身および)派生クラスからアクセスさせたいが、派生クラス外からはアクセスさせたくない」メンバは、protected (被保護)メンバとする
protected と private は、「派生クラスからのアクセス可否」のみが異なる。このため、継承を行わない場合は private と protected で差異は無い。

継承の種別によるアクセス指定の変化

継承の種別を private / protected / public から選択できるが、これにより 基本クラスにおいて private でないメンバの、派生クラスにおけるアクセス可否が変化する
いずれの場合でも、前述のとおり基本クラスの private メンバにはアクセス不可。
継承前後でアクセス指定が変化しない public 継承を主に用いるとよい

派生クラスにおけるアクセス可否
基本クラスにおけるアクセス指定 \ 継承種別private 継承protected 継承public 継承
private メンバ(アクセス不可)(アクセス不可)(アクセス不可)
protected メンバprivateprotectedprotected
public メンバprivateprotectedpublic

仮想関数

基本クラスで定義された関数を再定義し、異なる機能を持たせることができる。
詳細は 仮想関数 (Virtual Function)を参照。

多重継承

あるクラスが、複数のクラスを継承すること。 「複数の親を持つ」ことであり、「世代を重ねる」ことではない点に注意
複数のクラスの性質を併せ持つことができるが、多重継承を行うとプログラムが複雑化するうえに、多重継承が必要となる局面はそれほど多くないため、使用が禁じられることも多い。
(JavaやC#などは、多重継承をサポートしない。)
インタフェースも併せて参照。

注意が必要な点

派生クラスのインスタンスを生成する際は、派生クラス・基本クラス双方のコンストラクタが実行される。
このときの実行順序は、
基本クラスのコンストラクタ ⇒ 派生クラスのコンストラクタ
となる。
また、インスタンスを破棄する際は、
派生クラスのデストラクタ ⇒ 基本クラスのデストラクタ
で、 生成時とは逆順 となる。
実行時ポリモーフィズムを実現する場合は、デストラクタの実装に注意が必要である。 仮想デストラクタを参照のこと。